import sys
import os
import csv
from PyQt5.QtCore import QThread, pyqtSignal
from threading import Thread
from scihub import SciHub
from queue import Queue
import datetime

# 搜索线程
class DownThread(QThread):
    update_date = pyqtSignal(str)

    def __init__(self):
        super(DownThread, self).__init__()
        self.sh = SciHub()                      # 创建SCIHUB对象
        self.thread_num = 1                     # 下载线程
        self.stop_flag = False                  # 停止线程标志位
        self.save_path = ''
        self.download_queue = Queue()           # 下载队列
        self.success_down = 0
        self.fail_down = 0
        self.need_down = 0
        self.down_only = True                   # 仅下载标志位

    def run(self):
        self.down_paper()
        print("stopflag:{}".format(self.stop_flag))

    def down_paper(self):
        if self.down_only:
            res = self.read_csv()
            if res == -1 or res == 0:
                self.update_date.emit("2005返回")
                return

        save_path = self.build_dir()
        threads = []
        # 创建线程
        for i in range(self.thread_num):
            t = Thread(target=self.down_one, args=(save_path,))
            t.setDaemon(True)           # 设置线程为“守护线程”
            t.start()
            threads.append(t)
        # 线程同步
        for t in threads:
            t.join()

        self.update_date.emit('2003' + str(self.success_down) + '|' + str(self.need_down))

    def down_one(self, save_path):
        while self.stop_flag is False:
            if not self.download_queue.empty():
                paper_info = self.download_queue.get()
                paper_doi = paper_info['doi']
                paper_title = paper_info['title']

                if paper_doi.isdigit() or paper_doi == 'none':
                    self.update_date.emit('0000--> 文章{}无法下载'.format(paper_title))
                    self.fail_down += 1
                else:
                    res = self.sh.download(paper_doi, path=save_path + paper_title + ".pdf")
                    if 'err' in res:
                        self.update_date.emit("0000--> 文章下载失败！\n     题目：{}\n     error_code:{} \n".format(paper_title, res['err']))
                        self.fail_down += 1
                    else:
                        self.success_down += 1

                print("ready next")
                # 打印剩余待下载信息
                if self.down_only:
                    if self.need_down != self.download_queue.qsize():
                        self.need_down = self.download_queue.qsize()
                        self.update_date.emit("2002" + str(self.need_down))
                        self.update_date.emit("2004" + str(self.fail_down + self.success_down) + '|' + str(self.need_down))

    # 搜索并下载：将要下载的论文 doi和题目添加到队列
    def update_queue(self, dic):
        self.download_queue.put(dic)
        lent = self.download_queue.qsize()
        self.update_date.emit('2002' + str(lent))
        self.need_down += 1

    # 仅下载：读取csv文件 放入下载队列
    def read_csv(self):
        csv_path = self.save_path + "\\paper_info.csv"
        if not os.path.exists(csv_path):
            self.update_date.emit("0000--> 当前目录下未找到 paper_info.csv 文件，请检查后重试！")
            return -1
        with open(csv_path, "r", encoding="utf-8") as f:
            reader = csv.reader(f)
            for row in reader:
                dic = {'doi': row[0], 'title': row[1]}
                self.download_queue.put(dic)
            f.close()
        self.download_queue.get()           # 删除表头
        self.need_down = self.download_queue.qsize()
        if self.need_down == 0:
            self.update_date.emit("0000--> paper_info.csv为空，请检查后重试！")
            return 0
        self.update_date.emit("0000--> 共计 {} 篇，开始下载....".format(self.download_queue.qsize()))

    # 获取线程数和保存地址
    def get_ui_info(self, n, path):
        self.thread_num = n
        self.save_path = path

    # 停止当前线程
    def stop_thread(self, flag):
        if flag:
            self.stop_flag = True

    # 创建保存目录
    def build_dir(self):
        build_time = datetime.datetime.now().strftime("%Y_%m_%d")
        dir_path = self.save_path + "\\files_" + build_time + '\\'
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)
        return dir_path

    # 是否仅下载
    def down_status(self, flag):
        if flag:
            self.down_only = True
        else:
            self.down_only = False
